package com.lxl.testHd.myInputFormat.one;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IOUtils;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.InputSplit;
import org.apache.hadoop.mapreduce.RecordReader;
import org.apache.hadoop.mapreduce.TaskAttemptContext;
import org.apache.hadoop.mapreduce.lib.input.FileSplit;

import java.io.IOException;

/**
 * @author ：e_lixilin
 * @date ：2022/2/24 9:10
 * @description：
 * @modified By：自定义 记录读取器, key 为空, value 为文件内容
 */
public class SelfRecordReader extends RecordReader<Text, Text> {

    private FileSplit fileSplit  ;
    private Configuration config ;
    private boolean isProcessedFinish = false ;
    private Text value = new Text() ;
    private Text key = new Text() ;
    @Override
    public void initialize(InputSplit split, TaskAttemptContext context) throws IOException, InterruptedException {
        // 获取输入数据的文件切片
        this.fileSplit = (FileSplit)split;
        this.config = context.getConfiguration();
    }

    /**
     * 将读取到的文件放入key,value中
     * @return
     * @throws IOException
     * @throws InterruptedException
     */
    @Override
    public boolean nextKeyValue() throws IOException, InterruptedException {
        if (!isProcessedFinish) {
            FSDataInputStream is = null;
            try {
                // 获取fs
                Path path = fileSplit.getPath();
                FileSystem fs = path.getFileSystem(config);
                // 获取输入流
                is = fs.open(path);
                // 封装数据
                byte[] buf = new byte[(int) fileSplit.getLength()];
                IOUtils.readFully(is,buf,0,buf.length);
                value.set(buf,0,buf.length);
                key.set(path.toString());
            }finally {
                IOUtils.closeStream(is);
            }

            isProcessedFinish =true;
            return true;
        }
        return false;
    }

    @Override
    public Text getCurrentKey() throws IOException, InterruptedException {
        return this.key;
    }

    @Override
    public Text getCurrentValue() throws IOException, InterruptedException {
        return this.value;
    }

    @Override
    public float getProgress() throws IOException, InterruptedException {
        return isProcessedFinish ? 1.0f : 0.0f;
    }

    @Override
    public void close() throws IOException {

    }
}
